#pragma once
#include "task_queue.h"

cheetah_task* cheetah_task_create(int32 type, task_cb cb, void* ctx, void* param) {
	cheetah_task* t = (cheetah_task*)malloc(sizeof(cheetah_task));
	t->handle_ = -1;
	t->type_ = type;
	t->cb_ = cb;
	t->ctx_ = ctx;
	t->param_ = param;
	t->next_ = 0;
	return t;
}

void cheetah_tq_init(cheetah_tq* q, uint32 frame_task_max, cheetah_handle handle) {
	q->handle_ = handle;
	q->head_ = q->tail_ = 0;
	q->frame_task_max_ = frame_task_max;
	q->release_ = 0;
	q->ref_ = 0;
	q->lock_ = 0;
}

cheetah_tq* cheetah_tq_create(uint32 frame_task_max, cheetah_handle handle) {
	cheetah_tq* q = (cheetah_tq*)malloc(sizeof(cheetah_tq));
	cheetah_tq_init(q, frame_task_max, handle);
	return q;
}

void cheetah_tq_task_push(cheetah_tq* q, cheetah_task* t) {
	assert(!t->next_);
	ATOM_LOCK(&q->lock_);
	if (q->tail_) {
		q->tail_->next_ = t;
		q->tail_ = t;
	}
	else {
		q->head_ = q->tail_ = t;
	}
	ATOM_UNLOCK(&q->lock_);
}

cheetah_task* cheetah_tq_task_pop(cheetah_tq* q) {
	cheetah_task* t = 0;
	ATOM_LOCK(&q->lock_);
	if (q->head_) {
		t = q->head_;
		q->head_ = q->head_->next_;
		t->next_ = 0;
		if (!q->head_)
			q->tail_ = 0;
	}
	ATOM_UNLOCK(&q->lock_);
	return t;
}

